﻿using NX5Web.Controllers.WSSObjects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.WebSockets;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.UI.WebControls.WebParts;
using System.Web.WebSockets;
using static NX5Web.Controllers.WSSObjects.ExamLink;

namespace NX5Web.Controllers
{
    public class WSSController : ApiController
    {
         public class WssReturn
        {
            public String Action { set; get; }
            public String Params { set; get; }
        }

        [HttpGet]
        public HttpResponseMessage Connect()
        {
            if (HttpContext.Current.IsWebSocketRequest)
            {
                HttpContext.Current.AcceptWebSocketRequest(SocketEvent);
            }
            return new HttpResponseMessage(HttpStatusCode.SwitchingProtocols);
        }

        private async Task SocketEvent(AspNetWebSocketContext arg)
        {
            WebSocket socket = arg.WebSocket;
            while (true)
            {    
                ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]); 
                WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None); 

                if (socket.State == WebSocketState.Open)
                {
                    string message = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);

                    string returnMessage = "You send : " + message + ". at" + DateTime.Now.ToLongTimeString();
                    String CallbackData = "";

                    WSSRequest action = Newtonsoft.Json.JsonConvert.DeserializeObject<WSSRequest>(message);

                    List<WssResponse> MessageTo = new List<WssResponse>();
                    WssReturn WR = new WssReturn();

                    if (action.Action == "ExamConnect")
                    {
                        ExamInfo EI = Newtonsoft.Json.JsonConvert.DeserializeObject<ExamInfo>(action.Message);
                        EI.Socket = socket;
                        EI.IsConnected = true;


                        //学生链接
                        ExamLink EL = new ExamLink();
                        EL.EnterExam(EI.ExamId, EI);
                        if (EI.Role == "Student")
                        {
                            MessageTo = EL.GetExam(EI.ExamId);

                            WR.Action = action.Callback;
                            WR.Params = "{\"ExamId\":\"" + EI.ExamId + "\"}";
                        }
                    }
                    if(action.Action == "ExamProcess")
                    {
                        ExamInfo EI = Newtonsoft.Json.JsonConvert.DeserializeObject<ExamInfo>(action.Message);
                        EI.Socket = socket;
                        EI.IsConnected = true;


                        //学生链接
                        ExamLink EL = new ExamLink();
                        if (EI.Role == "Student")
                        {
                            MessageTo = EL.GetExam(EI.ExamId);
                            WR.Action = action.Callback;
                            WR.Params = "{\"ExamId\":\"" + EI.ExamId + "\",\"Msg\":\"" + EI.Msg + "\"}";
                        }
                    }
                    if(action.Action == "ExamFinish")
                    {
                        ExamInfo EI = Newtonsoft.Json.JsonConvert.DeserializeObject<ExamInfo>(action.Message);
                        EI.Socket = socket;
                        EI.IsConnected = true; 
                        //学生链接
                        ExamLink EL = new ExamLink(); 
                        if (EI.Role == "Student")
                        {
                            MessageTo = EL.GetExam(EI.ExamId);

                            WR.Action = action.Callback;
                            WR.Params = "{\"ExamId\":\""+ EI.ExamId +"\"}";
                        }
                    } 

                    returnMessage = Newtonsoft.Json.JsonConvert.SerializeObject(WR) ;


                    Byte[] bytes = System.Text.Encoding.UTF8.GetBytes(returnMessage);

                    await SendMessage(MessageTo, returnMessage, CancellationToken.None);
                }
                else
                {
                    break;
                }
            }
        }

        public async Task SendMessage(List<WssResponse> Users, String Message, CancellationToken cancellationToken)
        {
            if (Users != null && Users.Count > 0)
            {
                foreach (WssResponse u in Users)
                {
                    if (!u.IsConnected || u.Socket == null)
                    {
                        continue;
                    }
                    try
                    {
                        Newtonsoft.Json.JsonConvert.SerializeObject(u);
                    }
                    catch
                    {
                        //OnlineUsers.Offline(u.UserId);
                        continue;
                    }
                    Byte[] bytes = System.Text.Encoding.UTF8.GetBytes(Message);
                    await u.Socket.SendAsync(new ArraySegment<byte>(bytes),
                                      WebSocketMessageType.Text, true, cancellationToken);
                }
            }
        }
    }
}